const Workflow = require('../service/workflow')
const Controller = require('../prototype/Controller')
const editWorkflow = new Workflow({ name: 'tool' })
const { getTagByIds, updateById, createTool } = require('../service/tool')
const _ = require('lodash')
const { models } = require('../model')

editWorkflow.addFlowProcesses('stashed -> editing', [
  (eventRecord, { data }) => {
    eventRecord.editType = data.operation
    return eventRecord
  }
])

editWorkflow.addFlowProcesses('reviewing -> finished', [
  async (eventRecord) => {
    const data = _.cloneDeep(eventRecord.data)
    if (eventRecord.editType === 'create') {
      await createTool(data)
    }
    if (eventRecord.editType === 'edit') {
      await updateById(data._id, data)
    }
    return eventRecord
  }
])

editWorkflow.afterRecordProcess(async (record, rawRecord) => {
  if (record.tags) {
    record.tags = await getTagByIds(record.tags)
  }
})

const { ObjectID } = require('mongodb')

class ToolEdit extends Controller {
  constructor () {
    super({ model: models.Tool })
  }

  createWorkflow () {
    return async ({ request: req, response: res }) => {
      const { _user: user, body: data } = req
      const operation = req.ctx.params.operation
      // 组装数据
      data.operation = operation || 'edit'
      data._id = data._id || new ObjectID()
      try {
        const versionId = await editWorkflow.create({ user, data })
        return res.wrapper.succ({ versionId })
      } catch (err) {
        return res.wrapper.error('HANDLE_ERROR', err)
      }
    }
  }

  updateWorkflow () {
    return async ({ request: req, response: res }) => {
      try {
        await editWorkflow.update(req.ctx.params.id, 'setData', { user: req._user, data: req.body })
        return res.wrapper.succ({})
      } catch (err) {
        return res.wrapper.error('HANDLE_ERROR', err)
      }
    }
  }

  getReviewWorkflowList () {
    return async (ctx) => {
      await this._getWorkflowList(ctx, 'review')
    }
  }

  getEditWorkflowList () {
    return async (ctx) => {
      await this._getWorkflowList(ctx, 'edit')
    }
  }

  async _getWorkflowList ({ request: req, response: res }, type) {
    const query = req.query
    let { status, sort, limit, offset } = query
    status = {
      unreviewed: 'committed',
      reviewed: ['finished', 'rejected']
    }[status] || status
    const cond = {}
    if (query.keywords) {
      cond.$or = [
        { 'data.name': { $regex: `${query.keywords}` } },
        { 'data.description': { $regex: `${query.keywords}` } }
      ]
    }
    if (query.tags && query.tags.length > 0) {
      cond['data.tags'] = {
        $in: query.tags
      }
    }
    try {
      const retVal = await editWorkflow.getList(status, { offset, limit, sort, type, user: req._user, cond })
      return res.wrapper.succ(retVal)
    } catch (err) {
      console.error(err)
      return res.wrapper.error('HANDLE_ERROR', err)
    }
  }

  getDetail () {
    return async ({ request: req, response: res }) => {
      const versionId = req.ctx.params.id
      if (!versionId) {
        return res.wrapper.error('PARAMETERS_ERROR', '缺少编辑记录 ID')
      }
      try {
        const versionRecord = await editWorkflow.getDetail(versionId)
        return versionRecord ? res.wrapper.succ(versionRecord) : res.wrapper.error('NULL_ERROR')
      } catch (err) {
        return res.wrapper.error('HANDLE_ERROR', err)
      }
    }
  }

  updateWorkflowStatus () {
    return async ({ request: req, response: res }) => {
      const { _user: user, body: data } = req
      const versionId = req.ctx.params.id

      if (!versionId) {
        return res.wrapper.error('PARAMETERS_ERROR', '资源 ID 参数异常')
      }
      if (data.operation === 'reject') {
        if (!data.reviewerComment) {
          return res.wrapper.error('PARAMETERS_ERROR', '在拒绝审核的时候必须传递 comment 字段')
        }
      }
      try {
        await editWorkflow.update(versionId, data.operation, { user, data })
        return res.wrapper.succ(versionId)
      } catch (err) {
        return res.wrapper.error('HANDLE_ERROR', err)
      }
    }
  }

  async deleteWorkflow () {
    return async ({ request: req, response: res }) => {

    }
  }
}

module.exports = ToolEdit
